package utils

import (
	"fmt"
	"github.com/gorilla/websocket"
	"log"
)

// Client 表示一个 WebSocket 客户端
type Client struct {
	Conn *websocket.Conn
	Send chan []byte
}

// Hub 管理所有活动的客户端连接
type Hub struct {
	Clients    map[*Client]bool
	Register   chan *Client
	Unregister chan *Client
	Broadcast  chan []byte
}

// NewHub 创建一个新的 Hub 实例
func NewHub() *Hub {
	return &Hub{
		Clients:    make(map[*Client]bool),
		Register:   make(chan *Client),
		Unregister: make(chan *Client),
		Broadcast:  make(chan []byte),
	}
}

var H = NewHub()

func init() {
	go H.Run()
}

// Run 启动 Hub 循环，处理客户端的注册、注销和消息广播
func (h *Hub) Run() {
	for {
		select {
		case client := <-h.Register:
			log.Printf("客户端注册: %v", client.Conn.RemoteAddr())
			h.Clients[client] = true
		case client := <-h.Unregister:
			log.Printf("客户端注销: %v", client.Conn.RemoteAddr())
			if _, ok := h.Clients[client]; ok {
				delete(h.Clients, client)
				close(client.Send)
			}
		case message := <-h.Broadcast:
			log.Printf("广播消息: %s", message)
			for client := range h.Clients {
				select {
				case client.Send <- message:
					fmt.Println("客户端发生消息: " + string(message))
				default:
					close(client.Send)
					delete(h.Clients, client)
				}
			}
		}
	}
}

// ReadPump 从客户端读取消息并广播
func (c *Client) ReadPump() {
	defer func() {
		H.Unregister <- c
		c.Conn.Close()
	}()

	for {
		_, message, err := c.Conn.ReadMessage()
		if err != nil {
			if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
				log.Printf("error: %v", err)
			}
			break
		}
		H.Broadcast <- message
	}
}

// WritePump 向客户端发送消息
func (c *Client) WritePump() {
	defer c.Conn.Close()
	for message := range c.Send {
		err := c.Conn.WriteMessage(websocket.TextMessage, message)
		if err != nil {
			log.Println("Error sending message:", err)
			break
		}
	}
}
